1   /*
2    * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package java.awt;
26  
27  import java.util.Hashtable;
28  import java.util.Arrays;
29  
30  /**
31   * The <code>GridBagLayout</code> class is a flexible layout
32   * manager that aligns components vertically, horizontally or along their
33   * baseline without requiring that the components be of the same size.
34   * Each <code>GridBagLayout</code> object maintains a dynamic,
35   * rectangular grid of cells, with each component occupying
36   * one or more cells, called its <em>display area</em>.
37   * <p>
38   * Each component managed by a <code>GridBagLayout</code> is associated with
39   * an instance of {@link GridBagConstraints}.  The constraints object
40   * specifies where a component's display area should be located on the grid
41   * and how the component should be positioned within its display area.  In
42   * addition to its constraints object, the <code>GridBagLayout</code> also
43   * considers each component's minimum and preferred sizes in order to
44   * determine a component's size.
45   * <p>
46   * The overall orientation of the grid depends on the container's
47   * {@link ComponentOrientation} property.  For horizontal left-to-right
48   * orientations, grid coordinate (0,0) is in the upper left corner of the
49   * container with x increasing to the right and y increasing downward.  For
50   * horizontal right-to-left orientations, grid coordinate (0,0) is in the upper
51   * right corner of the container with x increasing to the left and y
52   * increasing downward.
53   * <p>
54   * To use a grid bag layout effectively, you must customize one or more
55   * of the <code>GridBagConstraints</code> objects that are associated
56   * with its components. You customize a <code>GridBagConstraints</code>
57   * object by setting one or more of its instance variables:
58   * <p>
59   * <dl>
60   * <dt>{@link GridBagConstraints#gridx},
61   * {@link GridBagConstraints#gridy}
62   * <dd>Specifies the cell containing the leading corner of the component's
63   * display area, where the cell at the origin of the grid has address
64   * <code>gridx&nbsp;=&nbsp;0</code>,
65   * <code>gridy&nbsp;=&nbsp;0</code>.  For horizontal left-to-right layout,
66   * a component's leading corner is its upper left.  For horizontal
67   * right-to-left layout, a component's leading corner is its upper right.
68   * Use <code>GridBagConstraints.RELATIVE</code> (the default value)
69   * to specify that the component be placed immediately following
70   * (along the x axis for <code>gridx</code> or the y axis for
71   * <code>gridy</code>) the component that was added to the container
72   * just before this component was added.
73   * <dt>{@link GridBagConstraints#gridwidth},
74   * {@link GridBagConstraints#gridheight}
75   * <dd>Specifies the number of cells in a row (for <code>gridwidth</code>)
76   * or column (for <code>gridheight</code>)
77   * in the component's display area.
78   * The default value is 1.
79   * Use <code>GridBagConstraints.REMAINDER</code> to specify
80   * that the component's display area will be from <code>gridx</code>
81   * to the last cell in the row (for <code>gridwidth</code>)
82   * or from <code>gridy</code> to the last cell in the column
83   * (for <code>gridheight</code>).
84   *
85   * Use <code>GridBagConstraints.RELATIVE</code> to specify
86   * that the component's display area will be from <code>gridx</code>
87   * to the next to the last cell in its row (for <code>gridwidth</code>
88   * or from <code>gridy</code> to the next to the last cell in its
89   * column (for <code>gridheight</code>).
90   *
91   * <dt>{@link GridBagConstraints#fill}
92   * <dd>Used when the component's display area
93   * is larger than the component's requested size
94   * to determine whether (and how) to resize the component.
95   * Possible values are
96   * <code>GridBagConstraints.NONE</code> (the default),
97   * <code>GridBagConstraints.HORIZONTAL</code>
98   * (make the component wide enough to fill its display area
99   * horizontally, but don't change its height),
100  * <code>GridBagConstraints.VERTICAL</code>
101  * (make the component tall enough to fill its display area
102  * vertically, but don't change its width), and
103  * <code>GridBagConstraints.BOTH</code>
104  * (make the component fill its display area entirely).
105  * <dt>{@link GridBagConstraints#ipadx},
106  * {@link GridBagConstraints#ipady}
107  * <dd>Specifies the component's internal padding within the layout,
108  * how much to add to the minimum size of the component.
109  * The width of the component will be at least its minimum width
110  * plus <code>ipadx</code> pixels. Similarly, the height of
111  * the component will be at least the minimum height plus
112  * <code>ipady</code> pixels.
113  * <dt>{@link GridBagConstraints#insets}
114  * <dd>Specifies the component's external padding, the minimum
115  * amount of space between the component and the edges of its display area.
116  * <dt>{@link GridBagConstraints#anchor}
117  * <dd>Specifies where the component should be positioned in its display area.
118  * There are three kinds of possible values: absolute, orientation-relative,
119  * and baseline-relative
120  * Orientation relative values are interpreted relative to the container's
121  * <code>ComponentOrientation</code> property while absolute values
122  * are not.  Baseline relative values are calculated relative to the
123  * baseline.  Valid values are:</dd>
124  * <p>
125  * <center><table BORDER=0 COLS=3 WIDTH=800
126  *        SUMMARY="absolute, relative and baseline values as described above">
127  * <tr>
128  * <th><P ALIGN="LEFT">Absolute Values</th>
129  * <th><P ALIGN="LEFT">Orientation Relative Values</th>
130  * <th><P ALIGN="LEFT">Baseline Relative Values</th>
131  * </tr>
132  * <tr>
133  * <td>
134  * <li><code>GridBagConstraints.NORTH</code></li>
135  * <li><code>GridBagConstraints.SOUTH</code></li>
136  * <li><code>GridBagConstraints.WEST</code></li>
137  * <li><code>GridBagConstraints.EAST</code></li>
138  * <li><code>GridBagConstraints.NORTHWEST</code></li>
139  * <li><code>GridBagConstraints.NORTHEAST</code></li>
140  * <li><code>GridBagConstraints.SOUTHWEST</code></li>
141  * <li><code>GridBagConstraints.SOUTHEAST</code></li>
142  * <li><code>GridBagConstraints.CENTER</code> (the default)</li>
143  * </td>
144  * <td>
145  * <li><code>GridBagConstraints.PAGE_START</code></li>
146  * <li><code>GridBagConstraints.PAGE_END</code></li>
147  * <li><code>GridBagConstraints.LINE_START</code></li>
148  * <li><code>GridBagConstraints.LINE_END</code></li>
149  * <li><code>GridBagConstraints.FIRST_LINE_START</code></li>
150  * <li><code>GridBagConstraints.FIRST_LINE_END</code></li>
151  * <li><code>GridBagConstraints.LAST_LINE_START</code></li>
152  * <li><code>GridBagConstraints.LAST_LINE_END</code></li>
153  * </td>
154  * <td>
155  * <li><code>GridBagConstraints.BASELINE</code></li>
156  * <li><code>GridBagConstraints.BASELINE_LEADING</code></li>
157  * <li><code>GridBagConstraints.BASELINE_TRAILING</code></li>
158  * <li><code>GridBagConstraints.ABOVE_BASELINE</code></li>
159  * <li><code>GridBagConstraints.ABOVE_BASELINE_LEADING</code></li>
160  * <li><code>GridBagConstraints.ABOVE_BASELINE_TRAILING</code></li>
161  * <li><code>GridBagConstraints.BELOW_BASELINE</code></li>
162  * <li><code>GridBagConstraints.BELOW_BASELINE_LEADING</code></li>
163  * <li><code>GridBagConstraints.BELOW_BASELINE_TRAILING</code></li>
164  * </td>
165  * </tr>
166  * </table></center><p>
167  * <dt>{@link GridBagConstraints#weightx},
168  * {@link GridBagConstraints#weighty}
169  * <dd>Used to determine how to distribute space, which is
170  * important for specifying resizing behavior.
171  * Unless you specify a weight for at least one component
172  * in a row (<code>weightx</code>) and column (<code>weighty</code>),
173  * all the components clump together in the center of their container.
174  * This is because when the weight is zero (the default),
175  * the <code>GridBagLayout</code> object puts any extra space
176  * between its grid of cells and the edges of the container.
177  * </dl>
178  * <p>
179  * Each row may have a baseline; the baseline is determined by the
180  * components in that row that have a valid baseline and are aligned
181  * along the baseline (the component's anchor value is one of {@code
182  * BASELINE}, {@code BASELINE_LEADING} or {@code BASELINE_TRAILING}).
183  * If none of the components in the row has a valid baseline, the row
184  * does not have a baseline.
185  * <p>
186  * If a component spans rows it is aligned either to the baseline of
187  * the start row (if the baseline-resize behavior is {@code
188  * CONSTANT_ASCENT}) or the end row (if the baseline-resize behavior
189  * is {@code CONSTANT_DESCENT}).  The row that the component is
190  * aligned to is called the <em>prevailing row</em>.
191  * <p>
192  * The following figure shows a baseline layout and includes a
193  * component that spans rows:
194  * <center><table summary="Baseline Layout">
195  * <tr ALIGN=CENTER>
196  * <td>
197  * <img src="doc-files/GridBagLayout-baseline.png"
198  *  alt="The following text describes this graphic (Figure 1)." ALIGN=center>
199  * </td>
200  * </table></center>
201  * This layout consists of three components:
202  * <ul><li>A panel that starts in row 0 and ends in row 1.  The panel
203  *   has a baseline-resize behavior of <code>CONSTANT_DESCENT</code> and has
204  *   an anchor of <code>BASELINE</code>.  As the baseline-resize behavior
205  *   is <code>CONSTANT_DESCENT</code> the prevailing row for the panel is
206  *   row 1.
207  * <li>Two buttons, each with a baseline-resize behavior of
208  *   <code>CENTER_OFFSET</code> and an anchor of <code>BASELINE</code>.
209  * </ul>
210  * Because the second button and the panel share the same prevailing row,
211  * they are both aligned along their baseline.
212  * <p>
213  * Components positioned using one of the baseline-relative values resize
214  * differently than when positioned using an absolute or orientation-relative
215  * value.  How components change is dictated by how the baseline of the
216  * prevailing row changes.  The baseline is anchored to the
217  * bottom of the display area if any components with the same prevailing row
218  * have a baseline-resize behavior of <code>CONSTANT_DESCENT</code>,
219  * otherwise the baseline is anchored to the top of the display area.
220  * The following rules dictate the resize behavior:
221  * <ul>
222  * <li>Resizable components positioned above the baseline can only
223  * grow as tall as the baseline.  For example, if the baseline is at 100
224  * and anchored at the top, a resizable component positioned above the
225  * baseline can never grow more than 100 units.
226  * <li>Similarly, resizable components positioned below the baseline can
227  * only grow as high as the difference between the display height and the
228  * baseline.
229  * <li>Resizable components positioned on the baseline with a
230  * baseline-resize behavior of <code>OTHER</code> are only resized if
231  * the baseline at the resized size fits within the display area.  If
232  * the baseline is such that it does not fit within the display area
233  * the component is not resized.
234  * <li>Components positioned on the baseline that do not have a
235  * baseline-resize behavior of <code>OTHER</code>
236  * can only grow as tall as {@code display height - baseline + baseline of component}.
237  * </ul>
238  * If you position a component along the baseline, but the
239  * component does not have a valid baseline, it will be vertically centered
240  * in its space.  Similarly if you have positioned a component relative
241  * to the baseline and none of the components in the row have a valid
242  * baseline the component is vertically centered.
243  * <p>
244  * The following figures show ten components (all buttons)
245  * managed by a grid bag layout.  Figure 2 shows the layout for a horizontal,
246  * left-to-right container and Figure 3 shows the layout for a horizontal,
247  * right-to-left container.
248  * <p>
249  * <center><table COLS=2 WIDTH=600 summary="layout">
250  * <tr ALIGN=CENTER>
251  * <td>
252  * <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." ALIGN=center HSPACE=10 VSPACE=7>
253  * </td>
254  * <td>
255  * <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." ALIGN=center HSPACE=10 VSPACE=7>
256  * </td>
257  * <tr ALIGN=CENTER>
258  * <td>Figure 2: Horizontal, Left-to-Right</td>
259  * <td>Figure 3: Horizontal, Right-to-Left</td>
260  * </tr>
261  * </table></center>
262  * <p>
263  * Each of the ten components has the <code>fill</code> field
264  * of its associated <code>GridBagConstraints</code> object
265  * set to <code>GridBagConstraints.BOTH</code>.
266  * In addition, the components have the following non-default constraints:
267  * <p>
268  * <ul>
269  * <li>Button1, Button2, Button3: <code>weightx&nbsp;=&nbsp;1.0</code>
270  * <li>Button4: <code>weightx&nbsp;=&nbsp;1.0</code>,
271  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
272  * <li>Button5: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
273  * <li>Button6: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.RELATIVE</code>
274  * <li>Button7: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
275  * <li>Button8: <code>gridheight&nbsp;=&nbsp;2</code>,
276  * <code>weighty&nbsp;=&nbsp;1.0</code>
277  * <li>Button9, Button 10:
278  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
279  * </ul>
280  * <p>
281  * Here is the code that implements the example shown above:
282  * <p>
283  * <hr><blockquote><pre>
284  * import java.awt.*;
285  * import java.util.*;
286  * import java.applet.Applet;
287  *
288  * public class GridBagEx1 extends Applet {
289  *
290  *     protected void makebutton(String name,
291  *                               GridBagLayout gridbag,
292  *                               GridBagConstraints c) {
293  *         Button button = new Button(name);
294  *         gridbag.setConstraints(button, c);
295  *         add(button);
296  *     }
297  *
298  *     public void init() {
299  *         GridBagLayout gridbag = new GridBagLayout();
300  *         GridBagConstraints c = new GridBagConstraints();
301  *
302  *         setFont(new Font("SansSerif", Font.PLAIN, 14));
303  *         setLayout(gridbag);
304  *
305  *         c.fill = GridBagConstraints.BOTH;
306  *         c.weightx = 1.0;
307  *         makebutton("Button1", gridbag, c);
308  *         makebutton("Button2", gridbag, c);
309  *         makebutton("Button3", gridbag, c);
310  *
311  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
312  *         makebutton("Button4", gridbag, c);
313  *
314  *         c.weightx = 0.0;                //reset to the default
315  *         makebutton("Button5", gridbag, c); //another row
316  *
317  *         c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
318  *         makebutton("Button6", gridbag, c);
319  *
320  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
321  *         makebutton("Button7", gridbag, c);
322  *
323  *         c.gridwidth = 1;                //reset to the default
324  *         c.gridheight = 2;
325  *         c.weighty = 1.0;
326  *         makebutton("Button8", gridbag, c);
327  *
328  *         c.weighty = 0.0;                //reset to the default
329  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
330  *         c.gridheight = 1;               //reset to the default
331  *         makebutton("Button9", gridbag, c);
332  *         makebutton("Button10", gridbag, c);
333  *
334  *         setSize(300, 100);
335  *     }
336  *
337  *     public static void main(String args[]) {
338  *         Frame f = new Frame("GridBag Layout Example");
339  *         GridBagEx1 ex1 = new GridBagEx1();
340  *
341  *         ex1.init();
342  *
343  *         f.add("Center", ex1);
344  *         f.pack();
345  *         f.setSize(f.getPreferredSize());
346  *         f.show();
347  *     }
348  * }
349  * </pre></blockquote><hr>
350  * <p>
351  * @author Doug Stein
352  * @author Bill Spitzak (orignial NeWS & OLIT implementation)
353  * @see       java.awt.GridBagConstraints
354  * @see       java.awt.GridBagLayoutInfo
355  * @see       java.awt.ComponentOrientation
356  * @since JDK1.0
357  */
358 public class GridBagLayout implements LayoutManager2,
359 java.io.Serializable {
360 
361     static final int EMPIRICMULTIPLIER = 2;
362     /**
363      * This field is no longer used to reserve arrays and keeped for backward
364      * compatibility. Previously, this was
365      * the maximum number of grid positions (both horizontal and
366      * vertical) that could be laid out by the grid bag layout.
367      * Current implementation doesn't impose any limits
368      * on the size of a grid.
369      */
370     protected static final int MAXGRIDSIZE = 512;
371 
372     /**
373      * The smallest grid that can be laid out by the grid bag layout.
374      */
375     protected static final int MINSIZE = 1;
376     /**
377      * The preferred grid size that can be laid out by the grid bag layout.
378      */
379     protected static final int PREFERREDSIZE = 2;
380 
381     /**
382      * This hashtable maintains the association between
383      * a component and its gridbag constraints.
384      * The Keys in <code>comptable</code> are the components and the
385      * values are the instances of <code>GridBagConstraints</code>.
386      *
387      * @serial
388      * @see java.awt.GridBagConstraints
389      */
390     protected Hashtable<Component,GridBagConstraints> comptable;
391 
392     /**
393      * This field holds a gridbag constraints instance
394      * containing the default values, so if a component
395      * does not have gridbag constraints associated with
396      * it, then the component will be assigned a
397      * copy of the <code>defaultConstraints</code>.
398      *
399      * @serial
400      * @see #getConstraints(Component)
401      * @see #setConstraints(Component, GridBagConstraints)
402      * @see #lookupConstraints(Component)
403      */
404     protected GridBagConstraints defaultConstraints;
405 
406     /**
407      * This field holds the layout information
408      * for the gridbag.  The information in this field
409      * is based on the most recent validation of the
410      * gridbag.
411      * If <code>layoutInfo</code> is <code>null</code>
412      * this indicates that there are no components in
413      * the gridbag or if there are components, they have
414      * not yet been validated.
415      *
416      * @serial
417      * @see #getLayoutInfo(Container, int)
418      */
419     protected GridBagLayoutInfo layoutInfo;
420 
421     /**
422      * This field holds the overrides to the column minimum
423      * width.  If this field is non-<code>null</code> the values are
424      * applied to the gridbag after all of the minimum columns
425      * widths have been calculated.
426      * If columnWidths has more elements than the number of
427      * columns, columns are added to the gridbag to match
428      * the number of elements in columnWidth.
429      *
430      * @serial
431      * @see #getLayoutDimensions()
432      */
433     public int columnWidths[];
434 
435     /**
436      * This field holds the overrides to the row minimum
437      * heights.  If this field is non-<code>null</code> the values are
438      * applied to the gridbag after all of the minimum row
439      * heights have been calculated.
440      * If <code>rowHeights</code> has more elements than the number of
441      * rows, rowa are added to the gridbag to match
442      * the number of elements in <code>rowHeights</code>.
443      *
444      * @serial
445      * @see #getLayoutDimensions()
446      */
447     public int rowHeights[];
448 
449     /**
450      * This field holds the overrides to the column weights.
451      * If this field is non-<code>null</code> the values are
452      * applied to the gridbag after all of the columns
453      * weights have been calculated.
454      * If <code>columnWeights[i]</code> &gt; weight for column i, then
455      * column i is assigned the weight in <code>columnWeights[i]</code>.
456      * If <code>columnWeights</code> has more elements than the number
457      * of columns, the excess elements are ignored - they do
458      * not cause more columns to be created.
459      *
460      * @serial
461      */
462     public double columnWeights[];
463 
464     /**
465      * This field holds the overrides to the row weights.
466      * If this field is non-<code>null</code> the values are
467      * applied to the gridbag after all of the rows
468      * weights have been calculated.
469      * If <code>rowWeights[i]</code> &gt; weight for row i, then
470      * row i is assigned the weight in <code>rowWeights[i]</code>.
471      * If <code>rowWeights</code> has more elements than the number
472      * of rows, the excess elements are ignored - they do
473      * not cause more rows to be created.
474      *
475      * @serial
476      */
477     public double rowWeights[];
478 
479     /**
480      * The component being positioned.  This is set before calling into
481      * <code>adjustForGravity</code>.
482      */
483     private Component componentAdjusting;
484 
485     /**
486      * Creates a grid bag layout manager.
487      */
488     public GridBagLayout () {
489         comptable = new Hashtable<Component,GridBagConstraints>();
490         defaultConstraints = new GridBagConstraints();
491     }
492 
493     /**
494      * Sets the constraints for the specified component in this layout.
495      * @param       comp the component to be modified
496      * @param       constraints the constraints to be applied
497      */
498     public void setConstraints(Component comp, GridBagConstraints constraints) {
499         comptable.put(comp, (GridBagConstraints)constraints.clone());
500     }
501 
502     /**
503      * Gets the constraints for the specified component.  A copy of
504      * the actual <code>GridBagConstraints</code> object is returned.
505      * @param       comp the component to be queried
506      * @return      the constraint for the specified component in this
507      *                  grid bag layout; a copy of the actual constraint
508      *                  object is returned
509      */
510     public GridBagConstraints getConstraints(Component comp) {
511         GridBagConstraints constraints = comptable.get(comp);
512         if (constraints == null) {
513             setConstraints(comp, defaultConstraints);
514             constraints = comptable.get(comp);
515         }
516         return (GridBagConstraints)constraints.clone();
517     }
518 
519     /**
520      * Retrieves the constraints for the specified component.
521      * The return value is not a copy, but is the actual
522      * <code>GridBagConstraints</code> object used by the layout mechanism.
523      * <p>
524      * If <code>comp</code> is not in the <code>GridBagLayout</code>,
525      * a set of default <code>GridBagConstraints</code> are returned.
526      * A <code>comp</code> value of <code>null</code> is invalid
527      * and returns <code>null</code>.
528      *
529      * @param       comp the component to be queried
530      * @return      the contraints for the specified component
531      */
532     protected GridBagConstraints lookupConstraints(Component comp) {
533         GridBagConstraints constraints = comptable.get(comp);
534         if (constraints == null) {
535             setConstraints(comp, defaultConstraints);
536             constraints = comptable.get(comp);
537         }
538         return constraints;
539     }
540 
541     /**
542      * Removes the constraints for the specified component in this layout
543      * @param       comp the component to be modified
544      */
545     private void removeConstraints(Component comp) {
546         comptable.remove(comp);
547     }
548 
549     /**
550      * Determines the origin of the layout area, in the graphics coordinate
551      * space of the target container.  This value represents the pixel
552      * coordinates of the top-left corner of the layout area regardless of
553      * the <code>ComponentOrientation</code> value of the container.  This
554      * is distinct from the grid origin given by the cell coordinates (0,0).
555      * Most applications do not call this method directly.
556      * @return     the graphics origin of the cell in the top-left
557      *             corner of the layout grid
558      * @see        java.awt.ComponentOrientation
559      * @since      JDK1.1
560      */
561     public Point getLayoutOrigin () {
562         Point origin = new Point(0,0);
563         if (layoutInfo != null) {
564             origin.x = layoutInfo.startx;
565             origin.y = layoutInfo.starty;
566         }
567         return origin;
568     }
569 
570     /**
571      * Determines column widths and row heights for the layout grid.
572      * <p>
573      * Most applications do not call this method directly.
574      * @return     an array of two arrays, containing the widths
575      *                       of the layout columns and
576      *                       the heights of the layout rows
577      * @since      JDK1.1
578      */
579     public int [][] getLayoutDimensions () {
580         if (layoutInfo == null)
581             return new int[2][0];
582 
583         int dim[][] = new int [2][];
584         dim[0] = new int[layoutInfo.width];
585         dim[1] = new int[layoutInfo.height];
586 
587         System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width);
588         System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height);
589 
590         return dim;
591     }
592 
593     /**
594      * Determines the weights of the layout grid's columns and rows.
595      * Weights are used to calculate how much a given column or row
596      * stretches beyond its preferred size, if the layout has extra
597      * room to fill.
598      * <p>
599      * Most applications do not call this method directly.
600      * @return      an array of two arrays, representing the
601      *                    horizontal weights of the layout columns
602      *                    and the vertical weights of the layout rows
603      * @since       JDK1.1
604      */
605     public double [][] getLayoutWeights () {
606         if (layoutInfo == null)
607             return new double[2][0];
608 
609         double weights[][] = new double [2][];
610         weights[0] = new double[layoutInfo.width];
611         weights[1] = new double[layoutInfo.height];
612 
613         System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width);
614         System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height);
615 
616         return weights;
617     }
618 
619     /**
620      * Determines which cell in the layout grid contains the point
621      * specified by <code>(x,&nbsp;y)</code>. Each cell is identified
622      * by its column index (ranging from 0 to the number of columns
623      * minus 1) and its row index (ranging from 0 to the number of
624      * rows minus 1).
625      * <p>
626      * If the <code>(x,&nbsp;y)</code> point lies
627      * outside the grid, the following rules are used.
628      * The column index is returned as zero if <code>x</code> lies to the
629      * left of the layout for a left-to-right container or to the right of
630      * the layout for a right-to-left container.  The column index is returned
631      * as the number of columns if <code>x</code> lies
632      * to the right of the layout in a left-to-right container or to the left
633      * in a right-to-left container.
634      * The row index is returned as zero if <code>y</code> lies above the
635      * layout, and as the number of rows if <code>y</code> lies
636      * below the layout.  The orientation of a container is determined by its
637      * <code>ComponentOrientation</code> property.
638      * @param      x    the <i>x</i> coordinate of a point
639      * @param      y    the <i>y</i> coordinate of a point
640      * @return     an ordered pair of indexes that indicate which cell
641      *             in the layout grid contains the point
642      *             (<i>x</i>,&nbsp;<i>y</i>).
643      * @see        java.awt.ComponentOrientation
644      * @since      JDK1.1
645      */
646     public Point location(int x, int y) {
647         Point loc = new Point(0,0);
648         int i, d;
649 
650         if (layoutInfo == null)
651             return loc;
652 
653         d = layoutInfo.startx;
654         if (!rightToLeft) {
655             for (i=0; i<layoutInfo.width; i++) {
656                 d += layoutInfo.minWidth[i];
657                 if (d > x)
658                     break;
659             }
660         } else {
661             for (i=layoutInfo.width-1; i>=0; i--) {
662                 if (d > x)
663                     break;
664                 d += layoutInfo.minWidth[i];
665             }
666             i++;
667         }
668         loc.x = i;
669 
670         d = layoutInfo.starty;
671         for (i=0; i<layoutInfo.height; i++) {
672             d += layoutInfo.minHeight[i];
673             if (d > y)
674                 break;
675         }
676         loc.y = i;
677 
678         return loc;
679     }
680 
681     /**
682      * Has no effect, since this layout manager does not use a per-component string.
683      */
684     public void addLayoutComponent(String name, Component comp) {
685     }
686 
687     /**
688      * Adds the specified component to the layout, using the specified
689      * <code>constraints</code> object.  Note that constraints
690      * are mutable and are, therefore, cloned when cached.
691      *
692      * @param      comp         the component to be added
693      * @param      constraints  an object that determines how
694      *                          the component is added to the layout
695      * @exception IllegalArgumentException if <code>constraints</code>
696      *            is not a <code>GridBagConstraint</code>
697      */
698     public void addLayoutComponent(Component comp, Object constraints) {
699         if (constraints instanceof GridBagConstraints) {
700             setConstraints(comp, (GridBagConstraints)constraints);
701         } else if (constraints != null) {
702             throw new IllegalArgumentException("cannot add to layout: constraints must be a GridBagConstraint");
703         }
704     }
705 
706     /**
707      * Removes the specified component from this layout.
708      * <p>
709      * Most applications do not call this method directly.
710      * @param    comp   the component to be removed.
711      * @see      java.awt.Container#remove(java.awt.Component)
712      * @see      java.awt.Container#removeAll()
713      */
714     public void removeLayoutComponent(Component comp) {
715         removeConstraints(comp);
716     }
717 
718     /**
719      * Determines the preferred size of the <code>parent</code>
720      * container using this grid bag layout.
721      * <p>
722      * Most applications do not call this method directly.
723      *
724      * @param     parent   the container in which to do the layout
725      * @see       java.awt.Container#getPreferredSize
726      * @return the preferred size of the <code>parent</code>
727      *  container
728      */
729     public Dimension preferredLayoutSize(Container parent) {
730         GridBagLayoutInfo info = getLayoutInfo(parent, PREFERREDSIZE);
731         return getMinSize(parent, info);
732     }
733 
734     /**
735      * Determines the minimum size of the <code>parent</code> container
736      * using this grid bag layout.
737      * <p>
738      * Most applications do not call this method directly.
739      * @param     parent   the container in which to do the layout
740      * @see       java.awt.Container#doLayout
741      * @return the minimum size of the <code>parent</code> container
742      */
743     public Dimension minimumLayoutSize(Container parent) {
744         GridBagLayoutInfo info = getLayoutInfo(parent, MINSIZE);
745         return getMinSize(parent, info);
746     }
747 
748     /**
749      * Returns the maximum dimensions for this layout given the components
750      * in the specified target container.
751      * @param target the container which needs to be laid out
752      * @see Container
753      * @see #minimumLayoutSize(Container)
754      * @see #preferredLayoutSize(Container)
755      * @return the maximum dimensions for this layout
756      */
757     public Dimension maximumLayoutSize(Container target) {
758         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
759     }
760 
761     /**
762      * Returns the alignment along the x axis.  This specifies how
763      * the component would like to be aligned relative to other
764      * components.  The value should be a number between 0 and 1
765      * where 0 represents alignment along the origin, 1 is aligned
766      * the furthest away from the origin, 0.5 is centered, etc.
767      * <p>
768      * @return the value <code>0.5f</code> to indicate centered
769      */
770     public float getLayoutAlignmentX(Container parent) {
771         return 0.5f;
772     }
773 
774     /**
775      * Returns the alignment along the y axis.  This specifies how
776      * the component would like to be aligned relative to other
777      * components.  The value should be a number between 0 and 1
778      * where 0 represents alignment along the origin, 1 is aligned
779      * the furthest away from the origin, 0.5 is centered, etc.
780      * <p>
781      * @return the value <code>0.5f</code> to indicate centered
782      */
783     public float getLayoutAlignmentY(Container parent) {
784         return 0.5f;
785     }
786 
787     /**
788      * Invalidates the layout, indicating that if the layout manager
789      * has cached information it should be discarded.
790      */
791     public void invalidateLayout(Container target) {
792     }
793 
794     /**
795      * Lays out the specified container using this grid bag layout.
796      * This method reshapes components in the specified container in
797      * order to satisfy the contraints of this <code>GridBagLayout</code>
798      * object.
799      * <p>
800      * Most applications do not call this method directly.
801      * @param parent the container in which to do the layout
802      * @see java.awt.Container
803      * @see java.awt.Container#doLayout
804      */
805     public void layoutContainer(Container parent) {
806         arrangeGrid(parent);
807     }
808 
809     /**
810      * Returns a string representation of this grid bag layout's values.
811      * @return     a string representation of this grid bag layout.
812      */
813     public String toString() {
814         return getClass().getName();
815     }
816 
817     /**
818      * Print the layout information.  Useful for debugging.
819      */
820 
821     /* DEBUG
822      *
823      *  protected void dumpLayoutInfo(GridBagLayoutInfo s) {
824      *    int x;
825      *
826      *    System.out.println("Col\tWidth\tWeight");
827      *    for (x=0; x<s.width; x++) {
828      *      System.out.println(x + "\t" +
829      *                   s.minWidth[x] + "\t" +
830      *                   s.weightX[x]);
831      *    }
832      *    System.out.println("Row\tHeight\tWeight");
833      *    for (x=0; x<s.height; x++) {
834      *      System.out.println(x + "\t" +
835      *                   s.minHeight[x] + "\t" +
836      *                   s.weightY[x]);
837      *    }
838      *  }
839      */
840 
841     /**
842      * Print the layout constraints.  Useful for debugging.
843      */
844 
845     /* DEBUG
846      *
847      *  protected void dumpConstraints(GridBagConstraints constraints) {
848      *    System.out.println(
849      *                 "wt " +
850      *                 constraints.weightx +
851      *                 " " +
852      *                 constraints.weighty +
853      *                 ", " +
854      *
855      *                 "box " +
856      *                 constraints.gridx +
857      *                 " " +
858      *                 constraints.gridy +
859      *                 " " +
860      *                 constraints.gridwidth +
861      *                 " " +
862      *                 constraints.gridheight +
863      *                 ", " +
864      *
865      *                 "min " +
866      *                 constraints.minWidth +
867      *                 " " +
868      *                 constraints.minHeight +
869      *                 ", " +
870      *
871      *                 "pad " +
872      *                 constraints.insets.bottom +
873      *                 " " +
874      *                 constraints.insets.left +
875      *                 " " +
876      *                 constraints.insets.right +
877      *                 " " +
878      *                 constraints.insets.top +
879      *                 " " +
880      *                 constraints.ipadx +
881      *                 " " +
882      *                 constraints.ipady);
883      *  }
884      */
885 
886     /**
887      * Fills in an instance of <code>GridBagLayoutInfo</code> for the
888      * current set of managed children. This requires three passes through the
889      * set of children:
890      *
891      * <ol>
892      * <li>Figure out the dimensions of the layout grid.
893      * <li>Determine which cells the components occupy.
894      * <li>Distribute the weights and min sizes amoung the rows/columns.
895      * </ol>
896      *
897      * This also caches the minsizes for all the children when they are
898      * first encountered (so subsequent loops don't need to ask again).
899      * <p>
900      * This method should only be used internally by
901      * <code>GridBagLayout</code>.
902      *
903      * @param parent  the layout container
904      * @param sizeflag either <code>PREFERREDSIZE</code> or
905      *   <code>MINSIZE</code>
906      * @return the <code>GridBagLayoutInfo</code> for the set of children
907      * @since 1.4
908      */
909     protected GridBagLayoutInfo getLayoutInfo(Container parent, int sizeflag) {
910         return GetLayoutInfo(parent, sizeflag);
911     }
912 
913     /*
914      * Calculate maximum array sizes to allocate arrays without ensureCapacity
915      * we may use preCalculated sizes in whole class because of upper estimation of
916      * maximumArrayXIndex and maximumArrayYIndex.
917      */
918 
919     private long[]  preInitMaximumArraySizes(Container parent){
920         Component components[] = parent.getComponents();
921         Component comp;
922         GridBagConstraints constraints;
923         int curX, curY;
924         int curWidth, curHeight;
925         int preMaximumArrayXIndex = 0;
926         int preMaximumArrayYIndex = 0;
927         long [] returnArray = new long[2];
928 
929         for (int compId = 0 ; compId < components.length ; compId++) {
930             comp = components[compId];
931             if (!comp.isVisible()) {
932                 continue;
933             }
934 
935             constraints = lookupConstraints(comp);
936             curX = constraints.gridx;
937             curY = constraints.gridy;
938             curWidth = constraints.gridwidth;
939             curHeight = constraints.gridheight;
940 
941             // -1==RELATIVE, means that column|row equals to previously added component,
942             // since each next Component with gridx|gridy == RELATIVE starts from
943             // previous position, so we should start from previous component which
944             // already used in maximumArray[X|Y]Index calculation. We could just increase
945             // maximum by 1 to handle situation when component with gridx=-1 was added.
946             if (curX < 0){
947                 curX = ++preMaximumArrayYIndex;
948             }
949             if (curY < 0){
950                 curY = ++preMaximumArrayXIndex;
951             }
952             // gridwidth|gridheight may be equal to RELATIVE (-1) or REMAINDER (0)
953             // in any case using 1 instead of 0 or -1 should be sufficient to for
954             // correct maximumArraySizes calculation
955             if (curWidth <= 0){
956                 curWidth = 1;
957             }
958             if (curHeight <= 0){
959                 curHeight = 1;
960             }
961 
962             preMaximumArrayXIndex = Math.max(curY + curHeight, preMaximumArrayXIndex);
963             preMaximumArrayYIndex = Math.max(curX + curWidth, preMaximumArrayYIndex);
964         } //for (components) loop
965         // Must specify index++ to allocate well-working arrays.
966         /* fix for 4623196.
967          * now return long array instead of Point
968          */
969         returnArray[0] = preMaximumArrayXIndex;
970         returnArray[1] = preMaximumArrayYIndex;
971         return returnArray;
972     } //PreInitMaximumSizes
973 
974     /**
975      * This method is obsolete and supplied for backwards
976      * compatability only; new code should call {@link
977      * #getLayoutInfo(java.awt.Container, int) getLayoutInfo} instead.
978      * This method is the same as <code>getLayoutInfo</code>;
979      * refer to <code>getLayoutInfo</code> for details on parameters
980      * and return value.
981      */
982     protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag) {
983         synchronized (parent.getTreeLock()) {
984             GridBagLayoutInfo r;
985             Component comp;
986             GridBagConstraints constraints;
987             Dimension d;
988             Component components[] = parent.getComponents();
989             // Code below will address index curX+curWidth in the case of yMaxArray, weightY
990             // ( respectively curY+curHeight for xMaxArray, weightX ) where
991             //  curX in 0 to preInitMaximumArraySizes.y
992             // Thus, the maximum index that could
993             // be calculated in the following code is curX+curX.
994             // EmpericMultier equals 2 because of this.
995 
996             int layoutWidth, layoutHeight;
997             int []xMaxArray;
998             int []yMaxArray;
999             int compindex, i, k, px, py, pixels_diff, nextSize;
1000             int curX = 0; // constraints.gridx
1001             int curY = 0; // constraints.gridy
1002             int curWidth = 1;  // constraints.gridwidth
1003             int curHeight = 1;  // constraints.gridheight
1004             int curRow, curCol;
1005             double weight_diff, weight;
1006             int maximumArrayXIndex = 0;
1007             int maximumArrayYIndex = 0;
1008             int anchor;
1009 
1010             /*
1011              * Pass #1
1012              *
1013              * Figure out the dimensions of the layout grid (use a value of 1 for
1014              * zero or negative widths and heights).
1015              */
1016 
1017             layoutWidth = layoutHeight = 0;
1018             curRow = curCol = -1;
1019             long [] arraySizes = preInitMaximumArraySizes(parent);
1020 
1021             /* fix for 4623196.
1022              * If user try to create a very big grid we can
1023              * get NegativeArraySizeException because of integer value
1024              * overflow (EMPIRICMULTIPLIER*gridSize might be more then Integer.MAX_VALUE).
1025              * We need to detect this situation and try to create a
1026              * grid with Integer.MAX_VALUE size instead.
1027              */
1028             maximumArrayXIndex = (EMPIRICMULTIPLIER * arraySizes[0] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[0];
1029             maximumArrayYIndex = (EMPIRICMULTIPLIER * arraySizes[1] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[1];
1030 
1031             if (rowHeights != null){
1032                 maximumArrayXIndex = Math.max(maximumArrayXIndex, rowHeights.length);
1033             }
1034             if (columnWidths != null){
1035                 maximumArrayYIndex = Math.max(maximumArrayYIndex, columnWidths.length);
1036             }
1037 
1038             xMaxArray = new int[maximumArrayXIndex];
1039             yMaxArray = new int[maximumArrayYIndex];
1040 
1041             boolean hasBaseline = false;
1042             for (compindex = 0 ; compindex < components.length ; compindex++) {
1043                 comp = components[compindex];
1044                 if (!comp.isVisible())
1045                     continue;
1046                 constraints = lookupConstraints(comp);
1047 
1048                 curX = constraints.gridx;
1049                 curY = constraints.gridy;
1050                 curWidth = constraints.gridwidth;
1051                 if (curWidth <= 0)
1052                     curWidth = 1;
1053                 curHeight = constraints.gridheight;
1054                 if (curHeight <= 0)
1055                     curHeight = 1;
1056 
1057                 /* If x or y is negative, then use relative positioning: */
1058                 if (curX < 0 && curY < 0) {
1059                     if (curRow >= 0)
1060                         curY = curRow;
1061                     else if (curCol >= 0)
1062                         curX = curCol;
1063                     else
1064                         curY = 0;
1065                 }
1066                 if (curX < 0) {
1067                     px = 0;
1068                     for (i = curY; i < (curY + curHeight); i++) {
1069                         px = Math.max(px, xMaxArray[i]);
1070                     }
1071 
1072                     curX = px - curX - 1;
1073                     if(curX < 0)
1074                         curX = 0;
1075                 }
1076                 else if (curY < 0) {
1077                     py = 0;
1078                     for (i = curX; i < (curX + curWidth); i++) {
1079                         py = Math.max(py, yMaxArray[i]);
1080                     }
1081                     curY = py - curY - 1;
1082                     if(curY < 0)
1083                         curY = 0;
1084                 }
1085 
1086                 /* Adjust the grid width and height
1087                  *  fix for 5005945: unneccessary loops removed
1088                  */
1089                 px = curX + curWidth;
1090                 if (layoutWidth < px) {
1091                     layoutWidth = px;
1092                 }
1093                 py = curY + curHeight;
1094                 if (layoutHeight < py) {
1095                     layoutHeight = py;
1096                 }
1097 
1098                 /* Adjust xMaxArray and yMaxArray */
1099                 for (i = curX; i < (curX + curWidth); i++) {
1100                     yMaxArray[i] =py;
1101                 }
1102                 for (i = curY; i < (curY + curHeight); i++) {
1103                     xMaxArray[i] = px;
1104                 }
1105 
1106 
1107                 /* Cache the current slave's size. */
1108                 if (sizeflag == PREFERREDSIZE)
1109                     d = comp.getPreferredSize();
1110                 else
1111                     d = comp.getMinimumSize();
1112                 constraints.minWidth = d.width;
1113                 constraints.minHeight = d.height;
1114                 if (calculateBaseline(comp, constraints, d)) {
1115                     hasBaseline = true;
1116                 }
1117 
1118                 /* Zero width and height must mean that this is the last item (or
1119                  * else something is wrong). */
1120                 if (constraints.gridheight == 0 && constraints.gridwidth == 0)
1121                     curRow = curCol = -1;
1122 
1123                 /* Zero width starts a new row */
1124                 if (constraints.gridheight == 0 && curRow < 0)
1125                     curCol = curX + curWidth;
1126 
1127                 /* Zero height starts a new column */
1128                 else if (constraints.gridwidth == 0 && curCol < 0)
1129                     curRow = curY + curHeight;
1130             } //for (components) loop
1131 
1132 
1133             /*
1134              * Apply minimum row/column dimensions
1135              */
1136             if (columnWidths != null && layoutWidth < columnWidths.length)
1137                 layoutWidth = columnWidths.length;
1138             if (rowHeights != null && layoutHeight < rowHeights.length)
1139                 layoutHeight = rowHeights.length;
1140 
1141             r = new GridBagLayoutInfo(layoutWidth, layoutHeight);
1142 
1143             /*
1144              * Pass #2
1145              *
1146              * Negative values for gridX are filled in with the current x value.
1147              * Negative values for gridY are filled in with the current y value.
1148              * Negative or zero values for gridWidth and gridHeight end the current
1149              *  row or column, respectively.
1150              */
1151 
1152             curRow = curCol = -1;
1153 
1154             Arrays.fill(xMaxArray, 0);
1155             Arrays.fill(yMaxArray, 0);
1156 
1157             int[] maxAscent = null;
1158             int[] maxDescent = null;
1159             short[] baselineType = null;
1160 
1161             if (hasBaseline) {
1162                 r.maxAscent = maxAscent = new int[layoutHeight];
1163                 r.maxDescent = maxDescent = new int[layoutHeight];
1164                 r.baselineType = baselineType = new short[layoutHeight];
1165                 r.hasBaseline = true;
1166             }
1167 
1168 
1169             for (compindex = 0 ; compindex < components.length ; compindex++) {
1170                 comp = components[compindex];
1171                 if (!comp.isVisible())
1172                     continue;
1173                 constraints = lookupConstraints(comp);
1174 
1175                 curX = constraints.gridx;
1176                 curY = constraints.gridy;
1177                 curWidth = constraints.gridwidth;
1178                 curHeight = constraints.gridheight;
1179 
1180                 /* If x or y is negative, then use relative positioning: */
1181                 if (curX < 0 && curY < 0) {
1182                     if(curRow >= 0)
1183                         curY = curRow;
1184                     else if(curCol >= 0)
1185                         curX = curCol;
1186                     else
1187                         curY = 0;
1188                 }
1189 
1190                 if (curX < 0) {
1191                     if (curHeight <= 0) {
1192                         curHeight += r.height - curY;
1193                         if (curHeight < 1)
1194                             curHeight = 1;
1195                     }
1196 
1197                     px = 0;
1198                     for (i = curY; i < (curY + curHeight); i++)
1199                         px = Math.max(px, xMaxArray[i]);
1200 
1201                     curX = px - curX - 1;
1202                     if(curX < 0)
1203                         curX = 0;
1204                 }
1205                 else if (curY < 0) {
1206                     if (curWidth <= 0) {
1207                         curWidth += r.width - curX;
1208                         if (curWidth < 1)
1209                             curWidth = 1;
1210                     }
1211 
1212                     py = 0;
1213                     for (i = curX; i < (curX + curWidth); i++){
1214                         py = Math.max(py, yMaxArray[i]);
1215                     }
1216 
1217                     curY = py - curY - 1;
1218                     if(curY < 0)
1219                         curY = 0;
1220                 }
1221 
1222                 if (curWidth <= 0) {
1223                     curWidth += r.width - curX;
1224                     if (curWidth < 1)
1225                         curWidth = 1;
1226                 }
1227 
1228                 if (curHeight <= 0) {
1229                     curHeight += r.height - curY;
1230                     if (curHeight < 1)
1231                         curHeight = 1;
1232                 }
1233 
1234                 px = curX + curWidth;
1235                 py = curY + curHeight;
1236 
1237                 for (i = curX; i < (curX + curWidth); i++) { yMaxArray[i] = py; }
1238                 for (i = curY; i < (curY + curHeight); i++) { xMaxArray[i] = px; }
1239 
1240                 /* Make negative sizes start a new row/column */
1241                 if (constraints.gridheight == 0 && constraints.gridwidth == 0)
1242                     curRow = curCol = -1;
1243                 if (constraints.gridheight == 0 && curRow < 0)
1244                     curCol = curX + curWidth;
1245                 else if (constraints.gridwidth == 0 && curCol < 0)
1246                     curRow = curY + curHeight;
1247 
1248                 /* Assign the new values to the gridbag slave */
1249                 constraints.tempX = curX;
1250                 constraints.tempY = curY;
1251                 constraints.tempWidth = curWidth;
1252                 constraints.tempHeight = curHeight;
1253 
1254                 anchor = constraints.anchor;
1255                 if (hasBaseline) {
1256                     switch(anchor) {
1257                     case GridBagConstraints.BASELINE:
1258                     case GridBagConstraints.BASELINE_LEADING:
1259                     case GridBagConstraints.BASELINE_TRAILING:
1260                         if (constraints.ascent >= 0) {
1261                             if (curHeight == 1) {
1262                                 maxAscent[curY] =
1263                                         Math.max(maxAscent[curY],
1264                                                  constraints.ascent);
1265                                 maxDescent[curY] =
1266                                         Math.max(maxDescent[curY],
1267                                                  constraints.descent);
1268                             }
1269                             else {
1270                                 if (constraints.baselineResizeBehavior ==
1271                                         Component.BaselineResizeBehavior.
1272                                         CONSTANT_DESCENT) {
1273                                     maxDescent[curY + curHeight - 1] =
1274                                         Math.max(maxDescent[curY + curHeight
1275                                                             - 1],
1276                                                  constraints.descent);
1277                                 }
1278                                 else {
1279                                     maxAscent[curY] = Math.max(maxAscent[curY],
1280                                                            constraints.ascent);
1281                                 }
1282                             }
1283                             if (constraints.baselineResizeBehavior ==
1284                                     Component.BaselineResizeBehavior.CONSTANT_DESCENT) {
1285                                 baselineType[curY + curHeight - 1] |=
1286                                         (1 << constraints.
1287                                          baselineResizeBehavior.ordinal());
1288                             }
1289                             else {
1290                                 baselineType[curY] |= (1 << constraints.
1291                                              baselineResizeBehavior.ordinal());
1292                             }
1293                         }
1294                         break;
1295                     case GridBagConstraints.ABOVE_BASELINE:
1296                     case GridBagConstraints.ABOVE_BASELINE_LEADING:
1297                     case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1298                         // Component positioned above the baseline.
1299                         // To make the bottom edge of the component aligned
1300                         // with the baseline the bottom inset is
1301                         // added to the descent, the rest to the ascent.
1302                         pixels_diff = constraints.minHeight +
1303                                 constraints.insets.top +
1304                                 constraints.ipady;
1305                         maxAscent[curY] = Math.max(maxAscent[curY],
1306                                                    pixels_diff);
1307                         maxDescent[curY] = Math.max(maxDescent[curY],
1308                                                     constraints.insets.bottom);
1309                         break;
1310                     case GridBagConstraints.BELOW_BASELINE:
1311                     case GridBagConstraints.BELOW_BASELINE_LEADING:
1312                     case GridBagConstraints.BELOW_BASELINE_TRAILING:
1313                         // Component positioned below the baseline.
1314                         // To make the top edge of the component aligned
1315                         // with the baseline the top inset is
1316                         // added to the ascent, the rest to the descent.
1317                         pixels_diff = constraints.minHeight +
1318                                 constraints.insets.bottom + constraints.ipady;
1319                         maxDescent[curY] = Math.max(maxDescent[curY],
1320                                                     pixels_diff);
1321                         maxAscent[curY] = Math.max(maxAscent[curY],
1322                                                    constraints.insets.top);
1323                         break;
1324                     }
1325                 }
1326             }
1327 
1328             r.weightX = new double[maximumArrayYIndex];
1329             r.weightY = new double[maximumArrayXIndex];
1330             r.minWidth = new int[maximumArrayYIndex];
1331             r.minHeight = new int[maximumArrayXIndex];
1332 
1333 
1334             /*
1335              * Apply minimum row/column dimensions and weights
1336              */
1337             if (columnWidths != null)
1338                 System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length);
1339             if (rowHeights != null)
1340                 System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length);
1341             if (columnWeights != null)
1342                 System.arraycopy(columnWeights, 0, r.weightX, 0,  Math.min(r.weightX.length, columnWeights.length));
1343             if (rowWeights != null)
1344                 System.arraycopy(rowWeights, 0, r.weightY, 0,  Math.min(r.weightY.length, rowWeights.length));
1345 
1346             /*
1347              * Pass #3
1348              *
1349              * Distribute the minimun widths and weights:
1350              */
1351 
1352             nextSize = Integer.MAX_VALUE;
1353 
1354             for (i = 1;
1355                  i != Integer.MAX_VALUE;
1356                  i = nextSize, nextSize = Integer.MAX_VALUE) {
1357                 for (compindex = 0 ; compindex < components.length ; compindex++) {
1358                     comp = components[compindex];
1359                     if (!comp.isVisible())
1360                         continue;
1361                     constraints = lookupConstraints(comp);
1362 
1363                     if (constraints.tempWidth == i) {
1364                         px = constraints.tempX + constraints.tempWidth; /* right column */
1365 
1366                         /*
1367                          * Figure out if we should use this slave\'s weight.  If the weight
1368                          * is less than the total weight spanned by the width of the cell,
1369                          * then discard the weight.  Otherwise split the difference
1370                          * according to the existing weights.
1371                          */
1372 
1373                         weight_diff = constraints.weightx;
1374                         for (k = constraints.tempX; k < px; k++)
1375                             weight_diff -= r.weightX[k];
1376                         if (weight_diff > 0.0) {
1377                             weight = 0.0;
1378                             for (k = constraints.tempX; k < px; k++)
1379                                 weight += r.weightX[k];
1380                             for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1381                                 double wt = r.weightX[k];
1382                                 double dx = (wt * weight_diff) / weight;
1383                                 r.weightX[k] += dx;
1384                                 weight_diff -= dx;
1385                                 weight -= wt;
1386                             }
1387                             /* Assign the remainder to the rightmost cell */
1388                             r.weightX[px-1] += weight_diff;
1389                         }
1390 
1391                         /*
1392                          * Calculate the minWidth array values.
1393                          * First, figure out how wide the current slave needs to be.
1394                          * Then, see if it will fit within the current minWidth values.
1395                          * If it will not fit, add the difference according to the
1396                          * weightX array.
1397                          */
1398 
1399                         pixels_diff =
1400                             constraints.minWidth + constraints.ipadx +
1401                             constraints.insets.left + constraints.insets.right;
1402 
1403                         for (k = constraints.tempX; k < px; k++)
1404                             pixels_diff -= r.minWidth[k];
1405                         if (pixels_diff > 0) {
1406                             weight = 0.0;
1407                             for (k = constraints.tempX; k < px; k++)
1408                                 weight += r.weightX[k];
1409                             for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1410                                 double wt = r.weightX[k];
1411                                 int dx = (int)((wt * ((double)pixels_diff)) / weight);
1412                                 r.minWidth[k] += dx;
1413                                 pixels_diff -= dx;
1414                                 weight -= wt;
1415                             }
1416                             /* Any leftovers go into the rightmost cell */
1417                             r.minWidth[px-1] += pixels_diff;
1418                         }
1419                     }
1420                     else if (constraints.tempWidth > i && constraints.tempWidth < nextSize)
1421                         nextSize = constraints.tempWidth;
1422 
1423 
1424                     if (constraints.tempHeight == i) {
1425                         py = constraints.tempY + constraints.tempHeight; /* bottom row */
1426 
1427                         /*
1428                          * Figure out if we should use this slave's weight.  If the weight
1429                          * is less than the total weight spanned by the height of the cell,
1430                          * then discard the weight.  Otherwise split it the difference
1431                          * according to the existing weights.
1432                          */
1433 
1434                         weight_diff = constraints.weighty;
1435                         for (k = constraints.tempY; k < py; k++)
1436                             weight_diff -= r.weightY[k];
1437                         if (weight_diff > 0.0) {
1438                             weight = 0.0;
1439                             for (k = constraints.tempY; k < py; k++)
1440                                 weight += r.weightY[k];
1441                             for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1442                                 double wt = r.weightY[k];
1443                                 double dy = (wt * weight_diff) / weight;
1444                                 r.weightY[k] += dy;
1445                                 weight_diff -= dy;
1446                                 weight -= wt;
1447                             }
1448                             /* Assign the remainder to the bottom cell */
1449                             r.weightY[py-1] += weight_diff;
1450                         }
1451 
1452                         /*
1453                          * Calculate the minHeight array values.
1454                          * First, figure out how tall the current slave needs to be.
1455                          * Then, see if it will fit within the current minHeight values.
1456                          * If it will not fit, add the difference according to the
1457                          * weightY array.
1458                          */
1459 
1460                         pixels_diff = -1;
1461                         if (hasBaseline) {
1462                             switch(constraints.anchor) {
1463                             case GridBagConstraints.BASELINE:
1464                             case GridBagConstraints.BASELINE_LEADING:
1465                             case GridBagConstraints.BASELINE_TRAILING:
1466                                 if (constraints.ascent >= 0) {
1467                                     if (constraints.tempHeight == 1) {
1468                                         pixels_diff =
1469                                             maxAscent[constraints.tempY] +
1470                                             maxDescent[constraints.tempY];
1471                                     }
1472                                     else if (constraints.baselineResizeBehavior !=
1473                                              Component.BaselineResizeBehavior.
1474                                              CONSTANT_DESCENT) {
1475                                         pixels_diff =
1476                                                 maxAscent[constraints.tempY] +
1477                                                 constraints.descent;
1478                                     }
1479                                     else {
1480                                         pixels_diff = constraints.ascent +
1481                                                 maxDescent[constraints.tempY +
1482                                                    constraints.tempHeight - 1];
1483                                     }
1484                                 }
1485                                 break;
1486                             case GridBagConstraints.ABOVE_BASELINE:
1487                             case GridBagConstraints.ABOVE_BASELINE_LEADING:
1488                             case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1489                                 pixels_diff = constraints.insets.top +
1490                                         constraints.minHeight +
1491                                         constraints.ipady +
1492                                         maxDescent[constraints.tempY];
1493                                 break;
1494                             case GridBagConstraints.BELOW_BASELINE:
1495                             case GridBagConstraints.BELOW_BASELINE_LEADING:
1496                             case GridBagConstraints.BELOW_BASELINE_TRAILING:
1497                                 pixels_diff = maxAscent[constraints.tempY] +
1498                                         constraints.minHeight +
1499                                         constraints.insets.bottom +
1500                                         constraints.ipady;
1501                                 break;
1502                             }
1503                         }
1504                         if (pixels_diff == -1) {
1505                             pixels_diff =
1506                                 constraints.minHeight + constraints.ipady +
1507                                 constraints.insets.top +
1508                                 constraints.insets.bottom;
1509                         }
1510                         for (k = constraints.tempY; k < py; k++)
1511                             pixels_diff -= r.minHeight[k];
1512                         if (pixels_diff > 0) {
1513                             weight = 0.0;
1514                             for (k = constraints.tempY; k < py; k++)
1515                                 weight += r.weightY[k];
1516                             for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1517                                 double wt = r.weightY[k];
1518                                 int dy = (int)((wt * ((double)pixels_diff)) / weight);
1519                                 r.minHeight[k] += dy;
1520                                 pixels_diff -= dy;
1521                                 weight -= wt;
1522                             }
1523                             /* Any leftovers go into the bottom cell */
1524                             r.minHeight[py-1] += pixels_diff;
1525                         }
1526                     }
1527                     else if (constraints.tempHeight > i &&
1528                              constraints.tempHeight < nextSize)
1529                         nextSize = constraints.tempHeight;
1530                 }
1531             }
1532             return r;
1533         }
1534     } //getLayoutInfo()
1535 
1536     /**
1537      * Calculate the baseline for the specified component.
1538      * If {@code c} is positioned along it's baseline, the baseline is
1539      * obtained and the {@code constraints} ascent, descent and
1540      * baseline resize behavior are set from the component; and true is
1541      * returned. Otherwise false is returned.
1542      */
1543     private boolean calculateBaseline(Component c,
1544                                       GridBagConstraints constraints,
1545                                       Dimension size) {
1546         int anchor = constraints.anchor;
1547         if (anchor == GridBagConstraints.BASELINE ||
1548                 anchor == GridBagConstraints.BASELINE_LEADING ||
1549                 anchor == GridBagConstraints.BASELINE_TRAILING) {
1550             // Apply the padding to the component, then ask for the baseline.
1551             int w = size.width + constraints.ipadx;
1552             int h = size.height + constraints.ipady;
1553             constraints.ascent = c.getBaseline(w, h);
1554             if (constraints.ascent >= 0) {
1555                 // Component has a baseline
1556                 int baseline = constraints.ascent;
1557                 // Adjust the ascent and descent to include the insets.
1558                 constraints.descent = h - constraints.ascent +
1559                             constraints.insets.bottom;
1560                 constraints.ascent += constraints.insets.top;
1561                 constraints.baselineResizeBehavior =
1562                         c.getBaselineResizeBehavior();
1563                 constraints.centerPadding = 0;
1564                 if (constraints.baselineResizeBehavior == Component.
1565                         BaselineResizeBehavior.CENTER_OFFSET) {
1566                     // Component has a baseline resize behavior of
1567                     // CENTER_OFFSET, calculate centerPadding and
1568                     // centerOffset (see the description of
1569                     // CENTER_OFFSET in the enum for detais on this
1570                     // algorithm).
1571                     int nextBaseline = c.getBaseline(w, h + 1);
1572                     constraints.centerOffset = baseline - h / 2;
1573                     if (h % 2 == 0) {
1574                         if (baseline != nextBaseline) {
1575                             constraints.centerPadding = 1;
1576                         }
1577                     }
1578                     else if (baseline == nextBaseline){
1579                         constraints.centerOffset--;
1580                         constraints.centerPadding = 1;
1581                     }
1582                 }
1583             }
1584             return true;
1585         }
1586         else {
1587             constraints.ascent = -1;
1588             return false;
1589         }
1590     }
1591 
1592     /**
1593      * Adjusts the x, y, width, and height fields to the correct
1594      * values depending on the constraint geometry and pads.
1595      * This method should only be used internally by
1596      * <code>GridBagLayout</code>.
1597      *
1598      * @param constraints the constraints to be applied
1599      * @param r the <code>Rectangle</code> to be adjusted
1600      * @since 1.4
1601      */
1602     protected void adjustForGravity(GridBagConstraints constraints,
1603                                     Rectangle r) {
1604         AdjustForGravity(constraints, r);
1605     }
1606 
1607     /**
1608      * This method is obsolete and supplied for backwards
1609      * compatability only; new code should call {@link
1610      * #adjustForGravity(java.awt.GridBagConstraints, java.awt.Rectangle)
1611      * adjustForGravity} instead.
1612      * This method is the same as <code>adjustForGravity</code>;
1613      * refer to <code>adjustForGravity</code> for details
1614      * on parameters.
1615      */
1616     protected void AdjustForGravity(GridBagConstraints constraints,
1617                                     Rectangle r) {
1618         int diffx, diffy;
1619         int cellY = r.y;
1620         int cellHeight = r.height;
1621 
1622         if (!rightToLeft) {
1623             r.x += constraints.insets.left;
1624         } else {
1625             r.x -= r.width - constraints.insets.right;
1626         }
1627         r.width -= (constraints.insets.left + constraints.insets.right);
1628         r.y += constraints.insets.top;
1629         r.height -= (constraints.insets.top + constraints.insets.bottom);
1630 
1631         diffx = 0;
1632         if ((constraints.fill != GridBagConstraints.HORIZONTAL &&
1633              constraints.fill != GridBagConstraints.BOTH)
1634             && (r.width > (constraints.minWidth + constraints.ipadx))) {
1635             diffx = r.width - (constraints.minWidth + constraints.ipadx);
1636             r.width = constraints.minWidth + constraints.ipadx;
1637         }
1638 
1639         diffy = 0;
1640         if ((constraints.fill != GridBagConstraints.VERTICAL &&
1641              constraints.fill != GridBagConstraints.BOTH)
1642             && (r.height > (constraints.minHeight + constraints.ipady))) {
1643             diffy = r.height - (constraints.minHeight + constraints.ipady);
1644             r.height = constraints.minHeight + constraints.ipady;
1645         }
1646 
1647         switch (constraints.anchor) {
1648           case GridBagConstraints.BASELINE:
1649               r.x += diffx/2;
1650               alignOnBaseline(constraints, r, cellY, cellHeight);
1651               break;
1652           case GridBagConstraints.BASELINE_LEADING:
1653               if (rightToLeft) {
1654                   r.x += diffx;
1655               }
1656               alignOnBaseline(constraints, r, cellY, cellHeight);
1657               break;
1658           case GridBagConstraints.BASELINE_TRAILING:
1659               if (!rightToLeft) {
1660                   r.x += diffx;
1661               }
1662               alignOnBaseline(constraints, r, cellY, cellHeight);
1663               break;
1664           case GridBagConstraints.ABOVE_BASELINE:
1665               r.x += diffx/2;
1666               alignAboveBaseline(constraints, r, cellY, cellHeight);
1667               break;
1668           case GridBagConstraints.ABOVE_BASELINE_LEADING:
1669               if (rightToLeft) {
1670                   r.x += diffx;
1671               }
1672               alignAboveBaseline(constraints, r, cellY, cellHeight);
1673               break;
1674           case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1675               if (!rightToLeft) {
1676                   r.x += diffx;
1677               }
1678               alignAboveBaseline(constraints, r, cellY, cellHeight);
1679               break;
1680           case GridBagConstraints.BELOW_BASELINE:
1681               r.x += diffx/2;
1682               alignBelowBaseline(constraints, r, cellY, cellHeight);
1683               break;
1684           case GridBagConstraints.BELOW_BASELINE_LEADING:
1685               if (rightToLeft) {
1686                   r.x += diffx;
1687               }
1688               alignBelowBaseline(constraints, r, cellY, cellHeight);
1689               break;
1690           case GridBagConstraints.BELOW_BASELINE_TRAILING:
1691               if (!rightToLeft) {
1692                   r.x += diffx;
1693               }
1694               alignBelowBaseline(constraints, r, cellY, cellHeight);
1695               break;
1696           case GridBagConstraints.CENTER:
1697               r.x += diffx/2;
1698               r.y += diffy/2;
1699               break;
1700           case GridBagConstraints.PAGE_START:
1701           case GridBagConstraints.NORTH:
1702               r.x += diffx/2;
1703               break;
1704           case GridBagConstraints.NORTHEAST:
1705               r.x += diffx;
1706               break;
1707           case GridBagConstraints.EAST:
1708               r.x += diffx;
1709               r.y += diffy/2;
1710               break;
1711           case GridBagConstraints.SOUTHEAST:
1712               r.x += diffx;
1713               r.y += diffy;
1714               break;
1715           case GridBagConstraints.PAGE_END:
1716           case GridBagConstraints.SOUTH:
1717               r.x += diffx/2;
1718               r.y += diffy;
1719               break;
1720           case GridBagConstraints.SOUTHWEST:
1721               r.y += diffy;
1722               break;
1723           case GridBagConstraints.WEST:
1724               r.y += diffy/2;
1725               break;
1726           case GridBagConstraints.NORTHWEST:
1727               break;
1728           case GridBagConstraints.LINE_START:
1729               if (rightToLeft) {
1730                   r.x += diffx;
1731               }
1732               r.y += diffy/2;
1733               break;
1734           case GridBagConstraints.LINE_END:
1735               if (!rightToLeft) {
1736                   r.x += diffx;
1737               }
1738               r.y += diffy/2;
1739               break;
1740           case GridBagConstraints.FIRST_LINE_START:
1741               if (rightToLeft) {
1742                   r.x += diffx;
1743               }
1744               break;
1745           case GridBagConstraints.FIRST_LINE_END:
1746               if (!rightToLeft) {
1747                   r.x += diffx;
1748               }
1749               break;
1750           case GridBagConstraints.LAST_LINE_START:
1751               if (rightToLeft) {
1752                   r.x += diffx;
1753               }
1754               r.y += diffy;
1755               break;
1756           case GridBagConstraints.LAST_LINE_END:
1757               if (!rightToLeft) {
1758                   r.x += diffx;
1759               }
1760               r.y += diffy;
1761               break;
1762           default:
1763               throw new IllegalArgumentException("illegal anchor value");
1764         }
1765     }
1766 
1767     /**
1768      * Positions on the baseline.
1769      *
1770      * @param cellY the location of the row, does not include insets
1771      * @param cellHeight the height of the row, does not take into account
1772      *        insets
1773      * @param r available bounds for the component, is padded by insets and
1774      *        ipady
1775      */
1776     private void alignOnBaseline(GridBagConstraints cons, Rectangle r,
1777                                  int cellY, int cellHeight) {
1778         if (cons.ascent >= 0) {
1779             if (cons.baselineResizeBehavior == Component.
1780                     BaselineResizeBehavior.CONSTANT_DESCENT) {
1781                 // Anchor to the bottom.
1782                 // Baseline is at (cellY + cellHeight - maxDescent).
1783                 // Bottom of component (maxY) is at baseline + descent
1784                 // of component. We need to subtract the bottom inset here
1785                 // as the descent in the constraints object includes the
1786                 // bottom inset.
1787                 int maxY = cellY + cellHeight -
1788                       layoutInfo.maxDescent[cons.tempY + cons.tempHeight - 1] +
1789                       cons.descent - cons.insets.bottom;
1790                 if (!cons.isVerticallyResizable()) {
1791                     // Component not resizable, calculate y location
1792                     // from maxY - height.
1793                     r.y = maxY - cons.minHeight;
1794                     r.height = cons.minHeight;
1795                 } else {
1796                     // Component is resizable. As brb is constant descent,
1797                     // can expand component to fill region above baseline.
1798                     // Subtract out the top inset so that components insets
1799                     // are honored.
1800                     r.height = maxY - cellY - cons.insets.top;
1801                 }
1802             }
1803             else {
1804                 // BRB is not constant_descent
1805                 int baseline; // baseline for the row, relative to cellY
1806                 // Component baseline, includes insets.top
1807                 int ascent = cons.ascent;
1808                 if (layoutInfo.hasConstantDescent(cons.tempY)) {
1809                     // Mixed ascent/descent in same row, calculate position
1810                     // off maxDescent
1811                     baseline = cellHeight - layoutInfo.maxDescent[cons.tempY];
1812                 }
1813                 else {
1814                     // Only ascents/unknown in this row, anchor to top
1815                     baseline = layoutInfo.maxAscent[cons.tempY];
1816                 }
1817                 if (cons.baselineResizeBehavior == Component.
1818                         BaselineResizeBehavior.OTHER) {
1819                     // BRB is other, which means we can only determine
1820                     // the baseline by asking for it again giving the
1821                     // size we plan on using for the component.
1822                     boolean fits = false;
1823                     ascent = componentAdjusting.getBaseline(r.width, r.height);
1824                     if (ascent >= 0) {
1825                         // Component has a baseline, pad with top inset
1826                         // (this follows from calculateBaseline which
1827                         // does the same).
1828                         ascent += cons.insets.top;
1829                     }
1830                     if (ascent >= 0 && ascent <= baseline) {
1831                         // Components baseline fits within rows baseline.
1832                         // Make sure the descent fits within the space as well.
1833                         if (baseline + (r.height - ascent - cons.insets.top) <=
1834                                 cellHeight - cons.insets.bottom) {
1835                             // It fits, we're good.
1836                             fits = true;
1837                         }
1838                         else if (cons.isVerticallyResizable()) {
1839                             // Doesn't fit, but it's resizable.  Try
1840                             // again assuming we'll get ascent again.
1841                             int ascent2 = componentAdjusting.getBaseline(
1842                                     r.width, cellHeight - cons.insets.bottom -
1843                                     baseline + ascent);
1844                             if (ascent2 >= 0) {
1845                                 ascent2 += cons.insets.top;
1846                             }
1847                             if (ascent2 >= 0 && ascent2 <= ascent) {
1848                                 // It'll fit
1849                                 r.height = cellHeight - cons.insets.bottom -
1850                                         baseline + ascent;
1851                                 ascent = ascent2;
1852                                 fits = true;
1853                             }
1854                         }
1855                     }
1856                     if (!fits) {
1857                         // Doesn't fit, use min size and original ascent
1858                         ascent = cons.ascent;
1859                         r.width = cons.minWidth;
1860                         r.height = cons.minHeight;
1861                     }
1862                 }
1863                 // Reset the components y location based on
1864                 // components ascent and baseline for row. Because ascent
1865                 // includes the baseline
1866                 r.y = cellY + baseline - ascent + cons.insets.top;
1867                 if (cons.isVerticallyResizable()) {
1868                     switch(cons.baselineResizeBehavior) {
1869                     case CONSTANT_ASCENT:
1870                         r.height = Math.max(cons.minHeight,cellY + cellHeight -
1871                                             r.y - cons.insets.bottom);
1872                         break;
1873                     case CENTER_OFFSET:
1874                         {
1875                             int upper = r.y - cellY - cons.insets.top;
1876                             int lower = cellY + cellHeight - r.y -
1877                                 cons.minHeight - cons.insets.bottom;
1878                             int delta = Math.min(upper, lower);
1879                             delta += delta;
1880                             if (delta > 0 &&
1881                                 (cons.minHeight + cons.centerPadding +
1882                                  delta) / 2 + cons.centerOffset != baseline) {
1883                                 // Off by 1
1884                                 delta--;
1885                             }
1886                             r.height = cons.minHeight + delta;
1887                             r.y = cellY + baseline -
1888                                 (r.height + cons.centerPadding) / 2 -
1889                                 cons.centerOffset;
1890                         }
1891                         break;
1892                     case OTHER:
1893                         // Handled above
1894                         break;
1895                     default:
1896                         break;
1897                     }
1898                 }
1899             }
1900         }
1901         else {
1902             centerVertically(cons, r, cellHeight);
1903         }
1904     }
1905 
1906     /**
1907      * Positions the specified component above the baseline. That is
1908      * the bottom edge of the component will be aligned along the baseline.
1909      * If the row does not have a baseline, this centers the component.
1910      */
1911     private void alignAboveBaseline(GridBagConstraints cons, Rectangle r,
1912                                     int cellY, int cellHeight) {
1913         if (layoutInfo.hasBaseline(cons.tempY)) {
1914             int maxY; // Baseline for the row
1915             if (layoutInfo.hasConstantDescent(cons.tempY)) {
1916                 // Prefer descent
1917                 maxY = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY];
1918             }
1919             else {
1920                 // Prefer ascent
1921                 maxY = cellY + layoutInfo.maxAscent[cons.tempY];
1922             }
1923             if (cons.isVerticallyResizable()) {
1924                 // Component is resizable. Top edge is offset by top
1925                 // inset, bottom edge on baseline.
1926                 r.y = cellY + cons.insets.top;
1927                 r.height = maxY - r.y;
1928             }
1929             else {
1930                 // Not resizable.
1931                 r.height = cons.minHeight + cons.ipady;
1932                 r.y = maxY - r.height;
1933             }
1934         }
1935         else {
1936             centerVertically(cons, r, cellHeight);
1937         }
1938     }
1939 
1940     /**
1941      * Positions below the baseline.
1942      */
1943     private void alignBelowBaseline(GridBagConstraints cons, Rectangle r,
1944                                     int cellY, int cellHeight) {
1945         if (layoutInfo.hasBaseline(cons.tempY)) {
1946             if (layoutInfo.hasConstantDescent(cons.tempY)) {
1947                 // Prefer descent
1948                 r.y = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY];
1949             }
1950             else {
1951                 // Prefer ascent
1952                 r.y = cellY + layoutInfo.maxAscent[cons.tempY];
1953             }
1954             if (cons.isVerticallyResizable()) {
1955                 r.height = cellY + cellHeight - r.y - cons.insets.bottom;
1956             }
1957         }
1958         else {
1959             centerVertically(cons, r, cellHeight);
1960         }
1961     }
1962 
1963     private void centerVertically(GridBagConstraints cons, Rectangle r,
1964                                   int cellHeight) {
1965         if (!cons.isVerticallyResizable()) {
1966             r.y += Math.max(0, (cellHeight - cons.insets.top -
1967                                 cons.insets.bottom - cons.minHeight -
1968                                 cons.ipady) / 2);
1969         }
1970     }
1971 
1972     /**
1973      * Figures out the minimum size of the
1974      * master based on the information from <code>getLayoutInfo</code>.
1975      * This method should only be used internally by
1976      * <code>GridBagLayout</code>.
1977      *
1978      * @param parent the layout container
1979      * @param info the layout info for this parent
1980      * @return a <code>Dimension</code> object containing the
1981      *   minimum size
1982      * @since 1.4
1983      */
1984     protected Dimension getMinSize(Container parent, GridBagLayoutInfo info) {
1985         return GetMinSize(parent, info);
1986     }
1987 
1988     /**
1989      * This method is obsolete and supplied for backwards
1990      * compatability only; new code should call {@link
1991      * #getMinSize(java.awt.Container, GridBagLayoutInfo) getMinSize} instead.
1992      * This method is the same as <code>getMinSize</code>;
1993      * refer to <code>getMinSize</code> for details on parameters
1994      * and return value.
1995      */
1996     protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info) {
1997         Dimension d = new Dimension();
1998         int i, t;
1999         Insets insets = parent.getInsets();
2000 
2001         t = 0;
2002         for(i = 0; i < info.width; i++)
2003             t += info.minWidth[i];
2004         d.width = t + insets.left + insets.right;
2005 
2006         t = 0;
2007         for(i = 0; i < info.height; i++)
2008             t += info.minHeight[i];
2009         d.height = t + insets.top + insets.bottom;
2010 
2011         return d;
2012     }
2013 
2014     transient boolean rightToLeft = false;
2015 
2016     /**
2017      * Lays out the grid.
2018      * This method should only be used internally by
2019      * <code>GridBagLayout</code>.
2020      *
2021      * @param parent the layout container
2022      * @since 1.4
2023      */
2024     protected void arrangeGrid(Container parent) {
2025         ArrangeGrid(parent);
2026     }
2027 
2028     /**
2029      * This method is obsolete and supplied for backwards
2030      * compatability only; new code should call {@link
2031      * #arrangeGrid(Container) arrangeGrid} instead.
2032      * This method is the same as <code>arrangeGrid</code>;
2033      * refer to <code>arrangeGrid</code> for details on the
2034      * parameter.
2035      */
2036     protected void ArrangeGrid(Container parent) {
2037         Component comp;
2038         int compindex;
2039         GridBagConstraints constraints;
2040         Insets insets = parent.getInsets();
2041         Component components[] = parent.getComponents();
2042         Dimension d;
2043         Rectangle r = new Rectangle();
2044         int i, diffw, diffh;
2045         double weight;
2046         GridBagLayoutInfo info;
2047 
2048         rightToLeft = !parent.getComponentOrientation().isLeftToRight();
2049 
2050         /*
2051          * If the parent has no slaves anymore, then don't do anything
2052          * at all:  just leave the parent's size as-is.
2053          */
2054         if (components.length == 0 &&
2055             (columnWidths == null || columnWidths.length == 0) &&
2056             (rowHeights == null || rowHeights.length == 0)) {
2057             return;
2058         }
2059 
2060         /*
2061          * Pass #1: scan all the slaves to figure out the total amount
2062          * of space needed.
2063          */
2064 
2065         info = getLayoutInfo(parent, PREFERREDSIZE);
2066         d = getMinSize(parent, info);
2067 
2068         if (parent.width < d.width || parent.height < d.height) {
2069             info = getLayoutInfo(parent, MINSIZE);
2070             d = getMinSize(parent, info);
2071         }
2072 
2073         layoutInfo = info;
2074         r.width = d.width;
2075         r.height = d.height;
2076 
2077         /*
2078          * DEBUG
2079          *
2080          * DumpLayoutInfo(info);
2081          * for (compindex = 0 ; compindex < components.length ; compindex++) {
2082          * comp = components[compindex];
2083          * if (!comp.isVisible())
2084          *      continue;
2085          * constraints = lookupConstraints(comp);
2086          * DumpConstraints(constraints);
2087          * }
2088          * System.out.println("minSize " + r.width + " " + r.height);
2089          */
2090 
2091         /*
2092          * If the current dimensions of the window don't match the desired
2093          * dimensions, then adjust the minWidth and minHeight arrays
2094          * according to the weights.
2095          */
2096 
2097         diffw = parent.width - r.width;
2098         if (diffw != 0) {
2099             weight = 0.0;
2100             for (i = 0; i < info.width; i++)
2101                 weight += info.weightX[i];
2102             if (weight > 0.0) {
2103                 for (i = 0; i < info.width; i++) {
2104                     int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight);
2105                     info.minWidth[i] += dx;
2106                     r.width += dx;
2107                     if (info.minWidth[i] < 0) {
2108                         r.width -= info.minWidth[i];
2109                         info.minWidth[i] = 0;
2110                     }
2111                 }
2112             }
2113             diffw = parent.width - r.width;
2114         }
2115 
2116         else {
2117             diffw = 0;
2118         }
2119 
2120         diffh = parent.height - r.height;
2121         if (diffh != 0) {
2122             weight = 0.0;
2123             for (i = 0; i < info.height; i++)
2124                 weight += info.weightY[i];
2125             if (weight > 0.0) {
2126                 for (i = 0; i < info.height; i++) {
2127                     int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight);
2128                     info.minHeight[i] += dy;
2129                     r.height += dy;
2130                     if (info.minHeight[i] < 0) {
2131                         r.height -= info.minHeight[i];
2132                         info.minHeight[i] = 0;
2133                     }
2134                 }
2135             }
2136             diffh = parent.height - r.height;
2137         }
2138 
2139         else {
2140             diffh = 0;
2141         }
2142 
2143         /*
2144          * DEBUG
2145          *
2146          * System.out.println("Re-adjusted:");
2147          * DumpLayoutInfo(info);
2148          */
2149 
2150         /*
2151          * Now do the actual layout of the slaves using the layout information
2152          * that has been collected.
2153          */
2154 
2155         info.startx = diffw/2 + insets.left;
2156         info.starty = diffh/2 + insets.top;
2157 
2158         for (compindex = 0 ; compindex < components.length ; compindex++) {
2159             comp = components[compindex];
2160             if (!comp.isVisible()){
2161                 continue;
2162             }
2163             constraints = lookupConstraints(comp);
2164 
2165             if (!rightToLeft) {
2166                 r.x = info.startx;
2167                 for(i = 0; i < constraints.tempX; i++)
2168                     r.x += info.minWidth[i];
2169             } else {
2170                 r.x = parent.width - (diffw/2 + insets.right);
2171                 for(i = 0; i < constraints.tempX; i++)
2172                     r.x -= info.minWidth[i];
2173             }
2174 
2175             r.y = info.starty;
2176             for(i = 0; i < constraints.tempY; i++)
2177                 r.y += info.minHeight[i];
2178 
2179             r.width = 0;
2180             for(i = constraints.tempX;
2181                 i < (constraints.tempX + constraints.tempWidth);
2182                 i++) {
2183                 r.width += info.minWidth[i];
2184             }
2185 
2186             r.height = 0;
2187             for(i = constraints.tempY;
2188                 i < (constraints.tempY + constraints.tempHeight);
2189                 i++) {
2190                 r.height += info.minHeight[i];
2191             }
2192 
2193             componentAdjusting = comp;
2194             adjustForGravity(constraints, r);
2195 
2196             /* fix for 4408108 - components were being created outside of the container */
2197             /* fix for 4969409 "-" replaced by "+"  */
2198             if (r.x < 0) {
2199                 r.width += r.x;
2200                 r.x = 0;
2201             }
2202 
2203             if (r.y < 0) {
2204                 r.height += r.y;
2205                 r.y = 0;
2206             }
2207 
2208             /*
2209              * If the window is too small to be interesting then
2210              * unmap it.  Otherwise configure it and then make sure
2211              * it's mapped.
2212              */
2213 
2214             if ((r.width <= 0) || (r.height <= 0)) {
2215                 comp.setBounds(0, 0, 0, 0);
2216             }
2217             else {
2218                 if (comp.x != r.x || comp.y != r.y ||
2219                     comp.width != r.width || comp.height != r.height) {
2220                     comp.setBounds(r.x, r.y, r.width, r.height);
2221                 }
2222             }
2223         }
2224     }
2225 
2226     // Added for serial backwards compatability (4348425)
2227     static final long serialVersionUID = 8838754796412211005L;
2228 }